"""
权限验证装饰器和工具函数
"""
from functools import wraps
from django.http import JsonResponse
from django.core.cache import cache
from django.conf import settings
from django.utils import timezone
from django.contrib.auth.models import AnonymousUser
import logging

logger = logging.getLogger(__name__)


def require_permissions(*permissions):
    """
    权限验证装饰器 - 用于函数视图
    
    用法:
    @require_permissions('auth.view_user', 'auth.change_user')
    def my_view(request):
        pass
    """
    def decorator(view_func):
        @wraps(view_func)
        def wrapper(request, *args, **kwargs):
            # 检查用户是否已认证
            if isinstance(request.user, AnonymousUser):
                return JsonResponse({
                    'code': 401,
                    'message': '用户未登录',
                    'timestamp': timezone.now().isoformat()
                }, status=401)
            
            # 超级用户直接通过
            if request.user.is_superuser:
                return view_func(request, *args, **kwargs)
            
            # 检查权限
            for permission in permissions:
                if not has_permission(request.user, permission):
                    return JsonResponse({
                        'code': 403,
                        'message': f'权限不足，需要权限: {permission}',
                        'timestamp': timezone.now().isoformat()
                    }, status=403)
            
            return view_func(request, *args, **kwargs)
        return wrapper
    return decorator


def require_any_permission(*permissions):
    """
    权限验证装饰器 - 只需要满足任一权限
    
    用法:
    @require_any_permission('auth.view_user', 'auth.change_user')
    def my_view(request):
        pass
    """
    def decorator(view_func):
        @wraps(view_func)
        def wrapper(request, *args, **kwargs):
            # 检查用户是否已认证
            if isinstance(request.user, AnonymousUser):
                return JsonResponse({
                    'code': 401,
                    'message': '用户未登录',
                    'timestamp': timezone.now().isoformat()
                }, status=401)
            
            # 超级用户直接通过
            if request.user.is_superuser:
                return view_func(request, *args, **kwargs)
            
            # 检查是否有任一权限
            for permission in permissions:
                if has_permission(request.user, permission):
                    return view_func(request, *args, **kwargs)
            
            return JsonResponse({
                'code': 403,
                'message': f'权限不足，需要以下任一权限: {", ".join(permissions)}',
                'timestamp': timezone.now().isoformat()
            }, status=403)
        return wrapper
    return decorator


def has_permission(user, permission):
    """
    检查用户是否具有指定权限（带缓存）
    
    Args:
        user: Django用户对象
        permission: 权限字符串，格式为 'app_label.codename'
    
    Returns:
        bool: 是否具有权限
    """
    # 匿名用户没有权限
    if isinstance(user, AnonymousUser):
        return False
    
    # 超级用户拥有所有权限
    if user.is_superuser:
        return True
    
    # 尝试从缓存获取用户权限
    cache_key = f'user_permissions:{user.id}'
    user_permissions = cache.get(cache_key)
    
    if user_permissions is None:
        # 缓存未命中，从数据库查询
        user_permissions = get_user_permissions(user)
        
        # 缓存权限列表
        cache_timeout = getattr(settings, 'PERMISSION_CACHE_SETTINGS', {}).get('USER_PERMISSIONS_TTL', 1800)
        cache.set(cache_key, user_permissions, cache_timeout)
    
    return permission in user_permissions


def get_user_permissions(user):
    """
    从数据库获取用户的所有权限
    
    Args:
        user: Django用户对象
    
    Returns:
        list: 权限字符串列表
    """
    try:
        # 导入模型（避免循环导入）
        from apps.permissions.models import UserRoleAssignment
        from django.db import models
        
        # 查询用户的有效角色分配
        active_assignments = UserRoleAssignment.objects.filter(
            user=user,
            status='active'
        ).filter(
            # 检查过期时间
            models.Q(expires_at__isnull=True) | models.Q(expires_at__gt=timezone.now())
        ).select_related('role__group')
        
        # 获取所有角色的权限
        permissions = set()
        for assignment in active_assignments:
            role_permissions = assignment.role.group.permissions.filter(
                permissionextension__status='active'
            ).values_list('codename', 'content_type__app_label')
            
            for codename, app_label in role_permissions:
                permissions.add(f'{app_label}.{codename}')
        
        return list(permissions)
        
    except Exception as e:
        logger.error(f"查询用户权限失败: {e}")
        return []


def get_user_roles(user):
    """
    获取用户的所有有效角色
    
    Args:
        user: Django用户对象
    
    Returns:
        list: 角色对象列表
    """
    try:
        from apps.permissions.models import UserRoleAssignment
        from django.db import models
        
        # 尝试从缓存获取
        cache_key = f'user_roles:{user.id}'
        user_roles = cache.get(cache_key)
        
        if user_roles is None:
            # 查询用户的有效角色分配
            active_assignments = UserRoleAssignment.objects.filter(
                user=user,
                status='active'
            ).filter(
                models.Q(expires_at__isnull=True) | models.Q(expires_at__gt=timezone.now())
            ).select_related('role')
            
            user_roles = [assignment.role for assignment in active_assignments]
            
            # 缓存角色列表
            cache_timeout = getattr(settings, 'PERMISSION_CACHE_SETTINGS', {}).get('USER_PERMISSIONS_TTL', 1800)
            cache.set(cache_key, user_roles, cache_timeout)
        
        return user_roles
        
    except Exception as e:
        logger.error(f"查询用户角色失败: {e}")
        return []


def clear_user_permission_cache(user_id):
    """
    清除指定用户的权限缓存
    
    Args:
        user_id: 用户ID
    """
    cache.delete(f'user_permissions:{user_id}')
    cache.delete(f'user_roles:{user_id}')


def clear_all_permission_cache():
    """
    清除所有权限相关缓存
    """
    try:
        from django.contrib.auth import get_user_model
        User = get_user_model()
        
        # 获取所有用户ID
        user_ids = User.objects.values_list('id', flat=True)
        
        # 清除所有用户权限缓存
        for user_id in user_ids:
            clear_user_permission_cache(user_id)
        
        logger.info("已清除所有权限缓存")
        
    except Exception as e:
        logger.error(f"清除权限缓存失败: {e}")


def check_object_permission(user, permission, obj):
    """
    检查用户对特定对象的权限
    
    Args:
        user: Django用户对象
        permission: 权限字符串
        obj: 目标对象
    
    Returns:
        bool: 是否具有权限
    """
    # 首先检查基础权限
    if not has_permission(user, permission):
        return False
    
    # 检查对象级权限（如果对象有owner字段）
    if hasattr(obj, 'owner') and obj.owner != user:
        # 只有管理员或对象所有者可以访问
        return user.is_staff or user.is_superuser
    
    # 检查对象级权限（如果对象有created_by字段）
    if hasattr(obj, 'created_by') and obj.created_by != user:
        return user.is_staff or user.is_superuser
    
    return True
